package com.gobrs.async.core.timer;

import com.gobrs.async.core.TaskActuator;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static com.gobrs.async.core.common.def.DefaultConfig.TASK_INITIALIZE;
import static com.gobrs.async.core.common.def.DefaultConfig.TASK_TIMEOUT;

public class TimerListener {

    private GobrsFutureTask gobrsFutureTask;

    private TaskActuator taskActuator;

    public TimerListener(GobrsFutureTask gobrsFutureTask,TaskActuator taskActuator){
        this.gobrsFutureTask=gobrsFutureTask;
        this.taskActuator=taskActuator;
    }
    /**
     * Tick.
     *
     * @throws ExecutionException   the execution exception
     * @throws InterruptedException the interrupted exception
     * @throws TimeoutException     the timeout exception
     */
    public void tick() throws ExecutionException, InterruptedException, TimeoutException{
        try {
            doTick();
        } catch (Exception exception) {
            gobrsFutureTask.cancel(true);
        }
    }

    /**
     * adjust interrupt
     * @return
     */
    private void doTick() {
        boolean b = !gobrsFutureTask.isDone()&& taskActuator.taskStatus().compareAndSet(TASK_INITIALIZE, TASK_TIMEOUT);
        if (b) {
            try {
                gobrsFutureTask.get(0, TimeUnit.MILLISECONDS);
            } catch (Exception e) {
                gobrsFutureTask.isMayStopIfRunning(true);
            }
        }
    }

    /**
     * Gets interval time in milliseconds.
     *
     * @return the interval time in milliseconds
     */
    public int getIntervalTimeInMilliseconds(){
        return taskActuator.task.getTimeoutInMilliseconds();
    }
}
